<?php
require_once('constants.php');
/**
 * The framework's main class. This is all static data and methods.
 */
class Framework {
    /**
     * Dispatcher.
     *
     * @var Dispatcher
     */
    static private $dispatcher = null;
    /**
     * Config.
     * @var Config
     */
    static private $config = null;
    /**
     * Database.
     * @var Database_Driver
     */
    static private $db = null;
    /**
     * Router.
     * @var Router
     */
    static private $router = null;
    /**
     * A list of database drivers.
     * @var array
     */
    static private $dbs = array();
    /**
     * A list of sessions.
     * @var array
     */
    static private $session = array();
    /**
     * Where the pages are stored.
     * @var string
     */
    static private $pagesdirectory = DEFAULT_PAGESDIRECTORY;
    /**
     * Where the views are stored.
     * @var string
     */
    static private $viewsdirectory = DEFAULT_VIEWSDIRECTORY;

    /**
     * Init.
     */
    static public function init() {
        require_once('Loader.php');
        Loader::registerAutoload();
    }

    /**
     * Get dispatcher.
     * @return Dispatcher
     */
    static public function getDispatcher() {
        if(self::$dispatcher === null) {
            self::$dispatcher = new Dispatcher(self::getRouter());
        }
        return self::$dispatcher;
    }
    
    static public function setDispatcher(Dispatcher $dispatcher) {
        self::$dispatcher = $dispatcher;
    }
    
    /**
     * Set the router object.
     * @param Router $router
     */
    static public function setRouter(Router $router) {
        self::$router = $router;
    }
    
    /**
     * Get router.
     * @return Router
     */
    static public function getRouter() {
        if(self::$router === null) {
            self::$router = new Router();
        }
        return self::$router;
    }

    /**
     * Get the directory where the pages live.
     * @return string
     */
	static public function getPagesDirectory() {
		return self::$pagesdirectory;
	}

    /**
     * Tell the framework where the pages live.
     * @param string $dir
     * @throws Framework_Exception
     */
	static public function setPagesDirectory($dir) {
	    if(!is_string($dir) || empty($dir)) {
	        throw new Framework_Exception('Pages directory must be a string.');
	    }
		self::$pagesdirectory = $dir;
	}

    /**
     * Get the directory where the views live.
     * @return string
     */
    static public function getViewsDirectory() {
        return self::$viewsdirectory;
    }

    /**
     * Tell the framework where the views live.
     * @param string $dir
     * @throws Framework_Exception
     */
    static public function setViewsDirectory($dir) {
	    if(!is_string($dir) || empty($dir)) {
	        throw new Framework_Exception('Views directory must be a string.');
	    }
        self::$viewsdirectory = $dir;
    }

    /**
     * Set the config object.
     * @param Config $config
     */
    static public function setConfig(Config $config) {
        self::$config = $config;
    }

    /**
     * Get the config object. If one doesn't already exist it's created.
     * @return Config
     */
    static public function getConfig() {
        if(self::$config === null) {
            self::$config = new Config();
        }
        return self::$config;
    }

    /**
     * Register a session object. Namespaces are supported.
     * @param Session $session
     */
    static public function registerSession(Session $session) {
        self::$session[$session->getNamespace()] = $session;
    }

    /**
     * Get the session, optionally with a namespace to get a subset.
     * @return Session
     */
    static public function getSession($namespace = false) {
        if(!$namespace) {
            return self::$session;
        }
        return self::$session[$namespace];
    }

    /**
     * Set the default database driver.
     * @param Database_Driver $db
     */
    static public function setDefaultDatabase(Database_Driver $db) {
        self::$db = $db;
    }

    /**
     * Get the default database driver. One will be created if it doesn't exist
     * and there is enough data. Exceptions will be thrown from the approriate objects.
     * @return Database_Driver
     */
    static public function getDefaultDatabase() {
        if(self::$db === null) {
            $defaultsection = self::getConfig()->getSection('general')->databaseconfigsection;
            self::$db = Database::factory(Framework::getConfig()->getSection($defaultsection));
        }
        return self::$db;
    }

    /**
     * Register a database driver object.
     * @param Database_Driver $db
     * @param string $name
     */
    static public function registerDatabase(Database_Driver $db, $name = '') {
        if($name == '') {
            $name = $db->getDriverName();
        }
        self::$dbs[$name] = $db;
    }

    /**
     * Get a registered database driver by name.
     * @return Database_Driver
     * @throws Database_Exception
     */
    static public function getDatabase($name) {
        if(!array_key_exists($name, self::$dbs)) {
            throw new Database_Exception("Database '$name' does not exist.");
        }
        return self::$dbs[$name];
    }
}
?>
